package com.wlyuan.gateway.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;

import java.util.Optional;

/**
 * @author c3
 */
@Slf4j
public class HttpUtils {
    private static final String UNKNOWN = "unknown";
    private static final String DOT = ",";
    private static final String LOOPBACK_IP = "127.0.0.1";

    private HttpUtils() {
    }

    public static String getClientIp(ServerHttpRequest request) {
        HttpHeaders httpHeaders = request.getHeaders();
        String clientIp = httpHeaders.getFirst("X-Requested-For");
        if (StringUtils.isEmpty(clientIp) || UNKNOWN.equalsIgnoreCase(clientIp)) {
            clientIp = httpHeaders.getFirst("X-Forwarded-For");
        }
        if (StringUtils.isEmpty(clientIp) || UNKNOWN.equalsIgnoreCase(clientIp)) {
            clientIp = httpHeaders.getFirst("Proxy-Client-IP");
        }
        if (StringUtils.isEmpty(clientIp) || UNKNOWN.equalsIgnoreCase(clientIp)) {
            clientIp = httpHeaders.getFirst("WL-Proxy-Client-IP");
        }
        if (StringUtils.isEmpty(clientIp) || UNKNOWN.equalsIgnoreCase(clientIp)) {
            clientIp = httpHeaders.getFirst("HTTP_CLIENT_IP");
        }
        if (StringUtils.isEmpty(clientIp) || UNKNOWN.equalsIgnoreCase(clientIp)) {
            clientIp = httpHeaders.getFirst("HTTP_X_FORWARDED_FOR");
        }
        if (StringUtils.isEmpty(clientIp) || UNKNOWN.equalsIgnoreCase(clientIp)) {
            clientIp = Optional.ofNullable(request.getRemoteAddress())
                    .map(ra -> ra.getAddress().getHostAddress())
                    .orElse(StringUtils.EMPTY);
        }
        if (StringUtils.isEmpty(clientIp)) {
            clientIp = LOOPBACK_IP;
        }
        if (clientIp.contains(DOT)) {
            clientIp = clientIp.substring(0, clientIp.indexOf(DOT));
        }
        return clientIp;
    }

    /**
     * 设置header， 先remove掉已存在的
     */
    public static void addHeader(ServerHttpRequest.Builder builder, String name, String value) {
        if (logger.isDebugEnabled()) {
            logger.debug("Add header:{}={}", name, value);
        }
        builder.headers(headers -> {
            headers.remove(name);
            headers.set(name, value);
        });
        MDC.put(name, value);
    }
}
